home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Plus
/
Graphics Plus.iso
/
general
/
viewers
/
polyview
/
polyvw20.lha
/
PolyView2.0
/
Examples
/
example.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-26
|
7KB
|
349 lines
/*
drop.c
NCSA Software Tools Group
March 7, 1991
DESCRIPTION
This program creates a sample HDF Vset data file useful for testing
PolyView. The file is an animation sequence of a set of cubes being dropped
onto a plane from random heights.
The created file is named "drop.hdf" and contains the following vgroups and
vdataatasets:
frameXXX Vgroups containing frames of simulation
px X dimension data set
py Y dimension data set
pz Z dimension data set
vz Y dimension data set
plist4 connectivity list for polygons and quadrilaterals
*/
/* INCLUDES */
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include "df.h"
#include "dfi.h"
#include "vg.h"
/* DEFINES */
#define POINTS 5000
#define VERTS 5000
#define BLOCKS 5000
#define TIMESTEP 0.01
#define ELASTICITY 0.7
#define CUBE 0.4
#define HALFCUBE (CUBE/2)
#define FILE "drop.hdf"
/* Random number generator information */
#define MAX_RND (1<<31)
#define RND(min,max) (double)(((((double)lcm_rnd())/(MAX_RND-1))*\
((double) max - (double) min)) + (double) min)
/* TYPES */
/* GLOBAL VARIABLES */
float bz[BLOCKS];
float bvz[BLOCKS];
float px[VERTS];
float py[VERTS];
float pz[VERTS];
float vz[VERTS];
int plist4[VERTS];
/* Size of the grid that blocks are scattered over. */
int x = 5, y = 5;
int frames = 100;
int np = 0;
int nv4 = 0;
/* PROTOTYPES */
unsigned long lcm_seed;
void lcm_randomize(unsigned long);
unsigned long lcm_rnd();
void init_vars();
void gen_data();
void write_to_hdf();
/* MAIN */
main(argc, argv)
int argc;
char * argv[];
{
/* Initialize global variables */
init_vars();
/* Write the data to the file */
write_to_hdf();
}
/* FUNCTION DECLARATIONS */
void
init_vars()
/* DESCRIPTION: Reinitializes all global variables to prepare for generating
another set of data.
*/
{
int i, j;
/* Initialize vertical positions of each block to a random value. */
/* Each block's initial velocity is zero. */
for (i = 0; i < x * y; i++) {
bz[i] = RND(0.5, 5.0);
bvz[i] = 0.0;
}
}
void rpp(float, float, float, float, float, float, float);
void
gen_data()
/* DESCRIPTION: Generates the next time step of the "simulation".
*/
{
int i, j;
nv4 = 0;
np = 0;
/* Build the polygons for each of the cubes. */
for (i = 0; i < x; i++) {
for (j = 0; j < y; j++) {
rpp(i-HALFCUBE,j-HALFCUBE,bz[i*y + j],
CUBE,CUBE,CUBE, bvz[i*y + j]);
}
}
/* Calculate the *next* timestep. Update each cube's position, */
/* then its velocity. If the position becomes negative, adjust */
/* accordingly. */
for (i = 0; i < x*y; i++) {
/* Update the position */
bz[i] += bvz[i];
#if 0
printf("v = %f\n", bz[i]);
#endif
/* If the block is below the z = 0 plane, then its position */
/* should be corrected -- it has "bounced". */
if (bz[i] <= 0.0) {
bz[i] = -bz[i] * ELASTICITY;
bvz[i] = -bvz[i] * ELASTICITY;
}
/* Update the velocity */
bvz[i] -= 9.81 * TIMESTEP;
}
}
int
add_pt(float x, float y, float z, float v)
/* DESCRIPTION: Adds points x, y, and z to the px, py, and pz arrays,
respectively. Also adds v to the vz array. Increments np.
*/
{
px[np] = x;
py[np] = y;
pz[np] = z;
vz[np] = v;
np++;
return np-1;
}
void
connect4(p0, p1, p2, p3)
int p0, p1, p2, p3;
/* DESCRIPTION: Connects points p0, p1, p2, p3 in the plist4 array.
Increments nv4. */
{
plist4[nv4*4+0] = p0+1;
plist4[nv4*4+1] = p1+1;
plist4[nv4*4+2] = p2+1;
plist4[nv4*4+3] = p3+1;
nv4++;
}
void
rpp(float x, float y, float z, float a, float b, float c, float v)
/* DESCRIPTION: Adds the vertices for a rectangular parallelpiped
with near corner (x, y, z) and far corner (x+a, y+b, z+c) to the
px, py, and pz arrays, and connects them in plist4. Also adds a
v value for each vertex.
*/
{
int p[8];
/* Add the points to the array */
p[0] = add_pt(x, y, z, v);
p[1] = add_pt(x, y+b, z, v);
p[2] = add_pt(x+a, y+b, z, v);
p[3] = add_pt(x+a, y, z, v);
p[4] = add_pt(x, y, z+c, v);
p[5] = add_pt(x, y+b, z+c, v);
p[6] = add_pt(x+a, y+b, z+c, v);
p[7] = add_pt(x+a, y, z+c, v);
/* Connect the dots */
connect4(p[0], p[1], p[2], p[3]);
connect4(p[5], p[6], p[2], p[1]);
connect4(p[0], p[4], p[5], p[1]);
connect4(p[0], p[3], p[7], p[4]);
connect4(p[2], p[6], p[7], p[3]);
connect4(p[7], p[6], p[5], p[4]);
}
void
write_to_hdf()
/* DESCRIPTION: Writes the data sets to the a new hdf file.
*/
{
DF * f;
VGROUP * root;
VGROUP * frame;
VDATA * vpx;
VDATA * vpy;
VDATA * vpz;
VDATA * vvz;
VDATA * vplist4;
char name[80];
int n;
/* Remove the file, if it already exists. */
unlink("drop.hdf");
/* Create the HDF file */
f = DFopen("drop.hdf", DFACC_ALL, 0);
/* Create the root and insert its children */
root = (VGROUP *) Vattach(f, -1, "w");
Vsetname(root, "/");
/* Create frames under the root group. Insert all of the */
/* data sets in there. */
for (n = 1; n <= frames; n++) {
/* Generate the next time step of data for the file */
gen_data();
/* Create the vdatas for the frames of the animation */
vpx = (VDATA *) VSattach(f, -1, "w");
VSsetname(vpx, "px");
VSsetfields(vpx, "px");
VSwrite(vpx, px, np, NO_INTERLACE);
vpy = (VDATA *) VSattach(f, -1, "w");
VSsetname(vpy, "py");
VSsetfields(vpy, "py");
VSwrite(vpy, py, np, NO_INTERLACE);
vpz = (VDATA *) VSattach(f, -1, "w");
VSsetname(vpz, "pz");
VSsetfields(vpz, "pz");
VSwrite(vpz, pz, np, NO_INTERLACE);
/* Create velocity dataset. */
/* Define a new data type for the vset file. */
vvz = (VDATA *) VSattach(f, -1, "w");
if (VSfdefine(vvz, "vz", LOCAL_FLOATTYPE, 1) == -1)
printf("ERROR: Problem defining 'vz'.\n");
VSsetname(vvz, "vz");
VSsetfields(vvz, "vz");
VSwrite(vvz, vz, np, NO_INTERLACE);
if (n == 1) {
/* Create connectivity dataset and insert it */
vplist4 = (VDATA *) VSattach(f, -1, "w");
VSfdefine(vplist4, "plist4", LOCAL_INTTYPE, 4);
VSsetname(vplist4, "plist4");
VSsetfields(vplist4, "plist4");
VSwrite(vplist4, plist4, nv4, NO_INTERLACE);
}
sprintf(name, "frame%02d", n);
frame = (VGROUP *) Vattach(f, -1, "w");
Vsetname(frame, name);
Vinsert(root, frame);
/* Insert the vdatas under the current frame */
Vinsert(frame, vpx);
Vinsert(frame, vpy);
Vinsert(frame, vpz);
Vinsert(frame, vvz);
if (n == 1) {
Vinsert(frame, vplist4);
}
VSdetach(vpx);
VSdetach(vpy);
VSdetach(vpz);
VSdetach(vvz);
if (n == 1) {
VSdetach(vplist4);
}
Vdetach(frame);
}
/* Close down the root group, now that we're done with it */
Vdetach(root);
DFclose(f);
}
/* RANDOM NUMBER GENERATOR FUNCTIONS */
void lcm_randomize(seed)
unsigned long seed;
{
lcm_seed = seed;
}
unsigned long lcm_rnd()
{
unsigned long rnd_val;
rnd_val = lcm_seed;
lcm_seed = ((314159269 * lcm_seed) + 453806245) % MAX_RND;
return (rnd_val);
}